package ca.uvic.group2;

import java.rmi.registry.*;
import ca.uvic.group2.server.*;
import ca.uvic.group2.api.*;
import java.net.*;


public class Bootloader {

    private static final int REGISTRY = 0;
    private static final int TRANSACTION = 1;
    private static final int DB = 2;
    private static final int LOG = 3;
    private static final int QUOTE = 4;
    private static final int LOCAL = 5;

    private static void usage() {
        System.out.println("Usage: Bootloader [command] [server]");
        System.out.println("\nCommands: start, stop");
        System.out.println("\nServers: local, registry, transaction, db, log, quote");
    }

    private static void doTest() throws Exception {
        InetAddress addr = InetAddress.getLocalHost();
        System.out.println("Localhost Name: " + addr.getHostName());
        System.out.println("Localhost Addr: " + addr.getHostAddress());


        TransactionServer s = new ServerFactory().getTransactionServer(0);
        RemoteServer rs = (RemoteServer)s;
        System.out.println(rs.getServerName());
        System.out.println(rs.getHostName());
    }

    public static void main(String[] args) throws Exception {
        if (args.length != 2) {
            usage();
            return;
        }

        if (args[1].equals("test")) {
            doTest();
            return;
        }

        String server = args[1];
        int serverId;
        if (server.equals("registry")) {
            serverId = REGISTRY;
        } else if (server.equals("transaction")) {
            serverId = TRANSACTION;
        } else if (server.equals("db")) {
            serverId = DB;
        } else if (server.equals("log")) {
            serverId = LOG;
        } else if (server.equals("quote")) {
            serverId = QUOTE;
        } else if (server.equals("local")) {
            serverId = LOCAL;
        } else {
            usage();
            return;
        }

        if (args[0].equals("start")) {
            start(serverId);
        } else if (args[0].equals("stop")) {
            stop(serverId);
        } else {
            usage();
        }

        return;
    }

    private static void start(int serverId) throws Exception {
        // Instantiate Servers.  JVM will remain running until they are released
        // from the RMI registry

        System.out.println("Starting servers...");

        switch (serverId) {
        case LOCAL :
            // start all servers locally
            ServerFactory.startServerRegistry();
            ServerFactory.startAuditServer();
            ServerFactory.startQuoteServer();
            ServerFactory.startDBServer();
            ServerFactory.startTransactionServer();
            break;
        case TRANSACTION :
            ServerFactory.startTransactionServer();
            break;
        case DB :
            ServerFactory.startDBServer();
            break;
        case QUOTE :
            ServerFactory.startQuoteServer();
            break;
        case LOG :
            ServerFactory.startAuditServer();
            break;
        case REGISTRY :
            ServerFactory.startServerRegistry();
            break;
        }

        System.out.println("Servers started.  Hit Ctrl+C to continue.");
    }

    private static void stop(int serverId) throws Exception {

        switch (serverId) {
        case LOCAL :
            // start all servers locally
            ServerFactory.serverStop(ServerFactory.TRANSACTION_PORT, TransactionServer.RMI_NAME);
            ServerFactory.serverStop(ServerFactory.QUOTE_PORT, QuoteServer.RMI_NAME);
            ServerFactory.serverStop(ServerFactory.DB_PORT, DBServer.RMI_NAME);
            ServerFactory.serverStop(ServerFactory.LOG_PORT, AuditLog.RMI_NAME);
            ServerFactory.serverStop(ServerFactory.REGISTRY_PORT, ServerRegistry.RMI_NAME);
            break;
        case TRANSACTION :
            ServerFactory.serverStop(ServerFactory.TRANSACTION_PORT, TransactionServer.RMI_NAME);
            break;
        case DB :
            ServerFactory.serverStop(ServerFactory.DB_PORT, DBServer.RMI_NAME);
            break;
        case QUOTE :
            ServerFactory.serverStop(ServerFactory.QUOTE_PORT, QuoteServer.RMI_NAME);
            break;
        case LOG :
            ServerFactory.serverStop(ServerFactory.LOG_PORT, AuditLog.RMI_NAME);
            break;
        case REGISTRY :
            ServerFactory.serverStop(ServerFactory.REGISTRY_PORT, ServerRegistry.RMI_NAME);
            break;
        }

        // Stop servers.  JVM will still remain running until all clients release their
        // refereces to the server.
    }

}
